<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simulated OS 10 TV For Production Environment - Home Search</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.1.3/css/bootstrap.min.css" rel="stylesheet">
    <style>
        body, html { background: #111 !important; overflow-x: hidden; }
        .top-bar { position: fixed; top: 0; left: 0; width: 100%; background: #222; z-index: 1000; border-bottom: 1px solid #eee; padding: 10px 0; }
        .top-bar .btn { margin-right: 8px; }
        .top-bar .fw-bold { color: #fff; }
        .sidebar { width: 200px; min-width: 200px; max-width: 200px; flex-shrink: 0; background: #222; height: calc(100vh - 56px); top: 56px; padding-top: 0; border-right: 1px solid #eee; position: fixed; left: 0; z-index: 1050; white-space: nowrap; }
        .sidebar .nav-link { color: #fff; font-size: 1.1em; margin-bottom: 8px; border-radius: 8px; transition: background 0.2s, color 0.2s; display: inline-block; float: none; }
        .sidebar .nav-link.active { background: #444; color: #4ea3ff; font-weight: bold; }
        .sidebar .nav-link:hover:not(.active) { background: #333; color: #4ea3ff; }
        .main-content { margin-left: 200px; width: calc(100vw - 200px); padding: 32px 0 0 32px; overflow-x: hidden; background: #111; min-height: calc(100vh - 56px); }
        .search-container { margin-bottom: 30px; }
        .search-header { margin-bottom: 20px; }
        .search-form { display: flex; gap: 15px; align-items: center; flex-wrap: wrap; padding-right: 32px; }
        .search-form input { flex: 1; min-width: 250px; padding: 12px 15px; border: 2px solid #444; border-radius: 8px; background: #333; color: #fff; font-size: 1em; }
        .search-form button { padding: 12px 25px; font-weight: 600; }
        .search-result-group { margin-bottom: 40px; }
        .search-result-title { color: #fff; font-size: 1.3em; margin-bottom: 16px; cursor: pointer; display: flex; align-items: center; gap: 8px; }
        .search-result-title:hover { color: #4ea3ff; }
        .search-result-list {
            display: flex;
            gap: 18px;
            flex-wrap: nowrap;
            padding-bottom: 8px;
            overflow-x: auto;
        }
        .search-result-list::-webkit-scrollbar { height: 8px; background: #222; border-radius: 6px; }
        .search-result-list::-webkit-scrollbar-thumb { background: #444; border-radius: 6px; }
        .search-result-list::-webkit-scrollbar-thumb:hover { background: #666; }
        .search-result-item { background: #222; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); width: 400px; min-width: 400px; overflow: hidden; transition: transform 0.2s, box-shadow 0.2s; cursor: pointer; }
        .search-result-item-vertical { width: 300px; min-width: 300px; }
        .search-result-item:hover, .search-result-item:focus { transform: scale(1.06); box-shadow: 0 4px 24px #00f4; outline: 2px solid #fff3; }
        .search-result-item img { width: 100%; height: 225px; object-fit: cover; border-radius: 12px 12px 0 0; }
        .search-result-item-vertical img { height: 400px; }
        .search-result-content { padding: 8px 12px 10px 12px; }
        .search-result-name, .search-result-value { white-space: normal; overflow: visible; text-overflow: initial; text-align: left; word-break: break-all; }
        .search-result-name { color: #fff; font-size: 1em; font-weight: 500; margin-bottom: 4px; }
        .search-result-value { color: #bbb; font-size: 0.95em; margin-bottom: 2px; }
        .search-result-date { color: #6cf; font-size: 0.92em; padding: 0 12px 2px 0; text-align: left; }
        .search-result-deeplinks { margin-top: 6px; }
        .search-result-deeplink { display: flex; align-items: center; gap: 4px; background: #181818; padding: 2px 8px 2px 2px; border-radius: 6px; margin-bottom: 4px; font-size: 0.85em; }
        .search-result-deeplink img { width: 22px; height: 22px; border-radius: 4px; }
        .search-result-deeplink .source-name { color: #fff; font-size: 0.97em; }
        .search-result-deeplink .source-id { color: #aaa; font-size: 0.85em; }
        .search-result-id { color: #aaa; font-size: 0.9em; margin-top: 4px; }
        .search-loading { text-align: center; color: #ccc; padding: 50px; }
        .search-no-results { text-align: center; color: #888; padding: 50px; }
        .search-error { text-align: center; color: #ff6b6b; padding: 50px; }
        #tokenDisplay.copied { position: relative; color: #fff !important; background: #28a745 !important; border-color: #28a745 !important; }
        #tokenDisplay.copied #tokenText { opacity: 0.3; }
        #tokenDisplay.copied::after { 
            content: "\2714 Copied!"; 
            position: absolute; 
            top: 0; left: 0; right: 0; bottom: 0; 
            display: flex; align-items: center; justify-content: center; 
            color: #fff; font-size: 1.1em; background: transparent; z-index: 2; 
        }
        .modal-custom-width .modal-dialog {
            max-width: 1020px;
        }
        .modal-custom-width .modal-content {
            background: #f8f9fa;
        }
    </style>
</head>
<body>
    <!-- Top Bar -->
    <div class="top-bar d-flex align-items-center px-4 justify-content-between">
        <span class="fw-bold" style="font-size:1.1em;">Simulated OS 10 TV For Production Environment</span>
        <div class="d-flex align-items-center">
            <button class="btn btn-success btn-sm me-2" id="tokenDisplay">
                <span id="tokenText">TOKEN_PLACEHOLDER</span>
            </button>
            <button class="btn btn-outline-primary btn-sm me-2" id="deviceInfoBtn">Device Info</button>
            <button class="btn btn-outline-warning btn-sm" id="configBtn">Configuration</button>
        </div>
    </div>
    <!-- 设备信息弹窗 -->
    <div class="modal fade modal-custom-width" id="deviceInfoModal" tabindex="-1">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Device Information</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <div id="deviceInfoContent"></div>
                </div>
            </div>
        </div>
    </div>
    <!-- 配置弹窗 -->
    <div class="modal fade" id="configModal" tabindex="-1">
        <div class="modal-dialog modal-lg">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Edit Device Configuration</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
                </div>
                <div class="modal-body">
                    <form id="configForm">
                        <div id="configFormFields" class="row g-3"></div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                    <button type="button" class="btn btn-outline-danger" id="configResetBtn">Reset</button>
                    <button type="button" class="btn btn-primary" id="configSaveBtn">Save & Reload</button>
                </div>
            </div>
        </div>
    </div>
    <div class="d-flex" style="margin-top:56px;">
        <!-- Sidebar -->
        <nav class="sidebar d-flex flex-column p-3">
            <a class="nav-link" href="OS10-home-your-top-choices.html" data-menu="your-top-choice">Your Top Choice</a>
            <a class="nav-link" href="OS10-home.html" data-menu="home">Home</a>
            <a class="nav-link" href="OS10-home-search.html" data-menu="home-search">Home Search</a>
            <a class="nav-link" href="OS10-discovery.html" data-menu="discovery">Discovery</a>
            <a class="nav-link" href="OS10-discovery-search.html" data-menu="discovery-search">Discovery Search</a>
        </nav>
        <!-- Main Content: Global Search -->
        <div class="main-content flex-grow-1">
            <div id="globalSection">
                <div class="search-container">
                    <div class="search-header">
                        <h3 style="color: #fff; margin-bottom: 10px;">Global Search</h3>
                        <p style="color: #ccc; font-size: 0.95em;">Search APP / MOVIE / SEASON / SHORTVIDEO / ACTOR / REC_CHANNEL_PROGRAM</p>
                    </div>
                    <div class="search-form">
                        <input type="text" id="searchKeyword" placeholder="Please enter a keyword, e.g. netflix">
                        <button id="searchBtn" class="btn btn-primary">Search</button>
                    </div>
                </div>
                <div id="searchResults" style="min-height: 200px;"></div>
            </div>
        </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script>
    // ========== Top buttons and global variables ==========
    let GLOBAL_PARAMS = JSON.parse(localStorage.getItem('GLOBAL_PARAMS')) || {
        productId: 'wtv10',
        brandId: '7',
        deviceSetId: '10bfa24f235519482a8b9b1c2ad7a3aef6',
        deviceType: 'WHALEOS_ZEASN_962D4_4K_MTP_P4',
        countryCode: 'DE',
        langCode: 'en',
        mac: '18:84:c1:f4:2c:60',
        functionType: 'TvLauncher',
        ifGetTvDetail: '1',
        iconResolution: '320*180',
        terminalType: 'TV',
        sn: '',
        appVersion: '20000043',
        androidVersion: '13',
        osType: 'WhaleOSA',
        clientIp: '217.111.87.254'
    };
    let globalToken = localStorage.getItem('globalToken') || '';
    let lockedClientIp = GLOBAL_PARAMS.clientIp;
    // 真实接口生成token
    async function fetchToken(force = false) {
        if (!force && globalToken) {
            $('#tokenText').text(globalToken);
            return;
        }
        const params = new URLSearchParams({ ...GLOBAL_PARAMS });
        try {
            const response = await $.ajax({
                url: 'https://saas.zeasn.tv/auth-api/api/v1/auth/deviceSign',
                method: 'POST',
                contentType: 'application/x-www-form-urlencoded',
                data: params.toString(),
                processData: false
            });
            if (response.errorCode !== "0") throw new Error('Failed to get token');
            globalToken = response.data.token;
            $('#tokenText').text(globalToken);
            localStorage.setItem('globalToken', globalToken);
        } catch (e) {
            $('#tokenText').text('Failed to generate');
            globalToken = '';
            localStorage.removeItem('globalToken');
        }
    }
    // 页面初始化自动生成token，按钮背景色为白色
    $(async function() {
        $('#tokenDisplay').removeClass('btn-success').addClass('btn-outline-success');
        if (!globalToken) {
            await fetchToken();
        } else {
            $('#tokenText').text(globalToken);
        }
    });
    // 设备信息渲染
    function renderDeviceInfo(data) {
        if (!data) {
            $('#deviceInfoContent').html('<div class="text-center py-4">No device data available</div>');
            return;
        }
        let rows = '';
        // 主体字段
        const mainFields = [
            ['Product ID', data.productId],
            ['App Version', data.appVersion],
            ['Android Version', data.androidVersion],
            ['Brand ID', data.brandId],
            ['Country Code', data.countryCode],
            ['DeviceSet ID', data.deviceSetId],
            ['Device Type', data.deviceType],
            ['MAC', data.mac],
            ['Language', data.langCode],
            ['IP', data.ip],
            ['OS Type', data.osType],
            ['Function Type', data.functionType],
            ['Token', data.token],
        ];
        mainFields.forEach(([k, v]) => {
            rows += `<tr><td>${k}:</td><td>${v ?? ''}</td></tr>`;
        });
        // tvDetailParam 展开
        if (data.tvDetailParam && typeof data.tvDetailParam === 'object') {
            rows += `<tr><td colspan='2'><b>tvDetailParam</b></td></tr>`;
            Object.entries(data.tvDetailParam).forEach(([k, v]) => {
                rows += `<tr><td style='padding-left:2em;'>${k}:</td><td>${v ?? ''}</td></tr>`;
            });
        }
        $('#deviceInfoContent').html(`<table class="device-info-table"><tbody>${rows}</tbody></table>`);
    }
    // Device Info按钮弹窗
    $('#deviceInfoBtn').click(async function() {
        if (!globalToken) {
            alert('请先生成token');
            return;
        }
        try {
            const res = await $.ajax({
                url: 'https://saas.zeasn.tv/sp/api/device/v1/column/token?token=' + encodeURIComponent(globalToken),
                method: 'GET'
            });
            if (res && res.errorCode === "1000") {
                renderDeviceInfo(null);
                $('#deviceInfoContent').html(`
                    <div class="text-danger text-center py-4">
                        Token expired (errorCode: 1000)<br>
                        <button id="refreshTokenBtn2" class="btn btn-danger btn-sm mt-3">Regenerate Token</button>
                    </div>
                `);
                $('#refreshTokenBtn2').off('click').on('click', async function() {
                    $('#refreshTokenBtn2').prop('disabled', true).text('生成中...');
                    await fetchToken(true);
                    location.reload();
                });
            } else if (res && res.data) {
                renderDeviceInfo(res.data);
            } else {
                renderDeviceInfo(null);
            }
        } catch (e) {
            renderDeviceInfo(null);
            alert('获取设备信息失败');
        }
        const modal = new bootstrap.Modal(document.getElementById('deviceInfoModal'));
        modal.show();
    });
    // 配置弹窗逻辑
    const CONFIG_KEYS = Object.keys(GLOBAL_PARAMS);
    $('#configBtn').click(function() {
        const $fields = $('#configFormFields').empty();
        CONFIG_KEYS.forEach(key => {
            let value = GLOBAL_PARAMS[key];
            $fields.append(`
                <div class="col-12 col-md-6">
                    <label class="form-label fw-bold">${key}</label>
                    <input type="text" class="form-control" name="${key}" value="${value ?? ''}">
                </div>
            `);
        });
        const modal = new bootstrap.Modal(document.getElementById('configModal'));
        modal.show();
    });
    // 配置弹窗保存并生成新token（真实接口）
    $('#configSaveBtn').off('click').on('click', async function() {
        const formArr = $('#configForm').serializeArray();
        formArr.forEach(({name, value}) => {
            GLOBAL_PARAMS[name] = value;
        });
        localStorage.setItem('GLOBAL_PARAMS', JSON.stringify(GLOBAL_PARAMS));
        $('#tokenText').text('Generating...');
        await fetchToken(true); // 强制刷新token
        // 关闭弹窗
        const modal = bootstrap.Modal.getInstance(document.getElementById('configModal'));
        if(modal) modal.hide();
        // 保存后自动刷新页面，确保配置生效
        setTimeout(()=>{ location.reload(); }, 300);
    });
    $('#configResetBtn').click(function() {
        const initial = {
            productId: 'wtv10',
            brandId: '7',
            deviceSetId: '10bfa24f235519482a8b9b1c2ad7a3aef6',
            deviceType: 'WHALEOS_ZEASN_962D4_4K_MTP_P4',
            countryCode: 'DE',
            langCode: 'en',
            mac: '18:84:c1:f4:2c:60',
            functionType: 'TvLauncher',
            ifGetTvDetail: '1',
            iconResolution: '320*180',
            terminalType: 'TV',
            sn: '',
            appVersion: '20000043',
            androidVersion: '13',
            osType: 'WhaleOSA',
            clientIp: '217.111.87.254'
        };
        Object.assign(GLOBAL_PARAMS, initial);
        $('#configForm input').each(function() {
            const key = $(this).attr('name');
            if (key in initial) $(this).val(initial[key]);
        });
        localStorage.removeItem('GLOBAL_PARAMS');
    });
    // ========== Global Search Function ==========
    // Search button click event
    $('#searchBtn').off('click').on('click', function() {
        const keyword = $('#searchKeyword').val().trim();
        if (!keyword) {
            alert('Please enter a search keyword');
            return;
        }
        if (!globalToken) {
            alert('Please generate token first');
            return;
        }
        performSearch(keyword);
    });
    // Search input enter event
    $('#searchKeyword').off('keydown').on('keydown', function(e) {
        if (e.key === 'Enter' || e.keyCode === 13) {
            $('#searchBtn').click();
        }
    });
    // Execute search
    async function performSearch(keyword) {
        const $results = $('#searchResults');
        $results.html('<div class="search-loading">Searching...</div>');
        try {
            const url = `https://saas.zeasn.tv/sp/api/device/v1/search/byContentType?token=${encodeURIComponent(globalToken)}&searchType=MOVIE%2CSEASON%2CSHORTVIDEO%2CAPP%2CACTOR%2CREC_CHANNEL_PROGRAM&txt=${encodeURIComponent(keyword)}&size=30&needPoster=true`;
            const response = await fetch(url);
            const data = await response.json();
            if (data.errorCode === "1000") {
                $results.html(`
                    <div class='text-danger' style='color:#ff6666;padding:32px 0;'>
                        Token expired (errorCode: 1000)<br>
                        <button id='refreshTokenBtn' class='btn btn-danger btn-sm mt-3'>Regenerate Token</button>
                    </div>
                `);
                $('#refreshTokenBtn').off('click').on('click', async function() {
                    $('#refreshTokenBtn').prop('disabled', true).text('Generating...');
                    await fetchToken(true);
                    location.reload();
                });
                return;
            }
            if (!data.data || data.data.length === 0) {
                $results.html('<div class="search-no-results">No related content found</div>');
                return;
            }
            renderSearchResults(data.data);
        } catch (error) {
            console.error('Search failed:', error);
            $results.html('<div class="search-error">Search failed, please try again later</div>');
        }
    }
    // Render search results
    function renderSearchResults(data) {
        const $results = $('#searchResults');
        $results.empty();
        data.forEach(group => {
            if (!group.resultList || group.resultList.length === 0) return;
            const $group = $('<div class="search-result-group"></div>');
            // 创建可折叠的标题
            const $title = $('<div class="search-result-title"></div>');
            const $icon = $('<span style="font-size: 1.2em;">▼</span>');
            const $titleText = $(`<span>${group.searchType}</span>`);
            $title.append($icon).append($titleText);
            // 创建结果列表
            const $list = $('<div class="search-result-list"></div>');
            group.resultList.forEach(item => {
                const name = item.name || '';
                const image = item.icon || item.poster || item.image || '';
                const sourceDeeplinks = item.sourceDeeplinks || [];
                // categories 展示
                let categoriesStr = '';
                if (item.moreInfo && Array.isArray(item.moreInfo.categories) && item.moreInfo.categories.length > 0) {
                    categoriesStr = `<div style='color:#ffb84d;font-size:0.97em;padding:0 0 2px 0;'>${item.moreInfo.categories.map(c => c.name).join(' / ')}</div>`;
                } else if (Array.isArray(item.categories) && item.categories.length > 0) {
                    categoriesStr = `<div style='color:#ffb84d;font-size:0.97em;padding:0 0 2px 0;'>${item.categories.join(' / ')}</div>`;
                }
                // videoScores 展示
                let videoScoresStr = '';
                if (item.moreInfo && Array.isArray(item.moreInfo.videoScores) && item.moreInfo.videoScores.length > 0) {
                    videoScoresStr = `<div style='color:#ffd580;font-size:0.97em;padding:0 0 2px 0;'>${item.moreInfo.videoScores.map(vs => `${vs.type||''}: ${vs.value||''}`).join(' / ')}</div>`;
                } else if (Array.isArray(item.videoScores) && item.videoScores.length > 0) {
                    videoScoresStr = `<div style='color:#ffd580;font-size:0.97em;padding:0 0 2px 0;'>${item.videoScores.map(vs => `${vs.name||''}: ${vs.score||''}`).join(' / ')}</div>`;
                }
                // seasonNumber / episodeCount 展示（仅SEASON类型）
                let seasonNumber = '';
                let episodeCount = '';
                if (item.seasonNumber !== undefined) {
                    seasonNumber = item.seasonNumber;
                } else if (item.moreInfo && item.moreInfo.seasonNumber !== undefined) {
                    seasonNumber = item.moreInfo.seasonNumber;
                } else if (item.value) {
                    try {
                        const v = typeof item.value === 'object' ? item.value : JSON.parse(item.value);
                        if (v.seasonNumber !== undefined) seasonNumber = v.seasonNumber;
                    } catch(e){}
                }
                if (item.episodeCount !== undefined) {
                    episodeCount = item.episodeCount;
                } else if (item.moreInfo && item.moreInfo.episodeCount !== undefined) {
                    episodeCount = item.moreInfo.episodeCount;
                } else if (item.value) {
                    try {
                        const v = typeof item.value === 'object' ? item.value : JSON.parse(item.value);
                        if (v.episodeCount !== undefined) episodeCount = v.episodeCount;
                    } catch(e){}
                }
                let isSeasonType = (item.objectType === 'SEASON' || group.searchType === 'SEASON' || (item.value && typeof item.value === 'object' && item.value.objectType === 'SEASON'));
                let seasonInfoStr = '';
                if (isSeasonType && (seasonNumber || episodeCount)) {
                    let arr = [];
                    if (seasonNumber) arr.push('S' + seasonNumber);
                    if (episodeCount) arr.push(episodeCount + ' episodes');
                    seasonInfoStr = `<div style='color:#ffd580;font-size:0.97em;padding:0 0 2px 0;'>${arr.join(' / ')}</div>`;
                }
                // duration 展示（仅MOVIE/VIDEO/PROGRAM类型）
                let duration = '';
                if (item.duration !== undefined) {
                    duration = item.duration;
                } else if (item.moreInfo && item.moreInfo.duration !== undefined) {
                    duration = item.moreInfo.duration;
                } else if (item.value) {
                    try {
                        const v = typeof item.value === 'object' ? item.value : JSON.parse(item.value);
                        if (v.duration !== undefined) duration = v.duration;
                    } catch(e){}
                }
                function formatDuration(d) {
                    d = Number(d);
                    if (isNaN(d) || d <= 0) return '';
                    const h = Math.floor(d / 3600);
                    const m = Math.floor((d % 3600) / 60);
                    const s = d % 60;
                    let arr = [];
                    if (h > 0) arr.push(h + 'h');
                    if (m > 0) arr.push(m + 'm');
                    if (s > 0 || arr.length === 0) arr.push(s + 's');
                    return arr.join(' ');
                }
                let isMovieType = (
                    item.objectType === 'MOVIE' || item.objectType === 'VIDEO' || item.objectType === 'PROGRAM' ||
                    group.searchType === 'MOVIE' || group.searchType === 'VIDEO' || group.searchType === 'PROGRAM' ||
                    (item.value && typeof item.value === 'object' && (
                        item.value.objectType === 'MOVIE' || item.value.objectType === 'VIDEO' || item.value.objectType === 'PROGRAM'
                    ))
                );
                let durationStr = '';
                if (isMovieType && duration) {
                    durationStr = `<div class='search-result-date'>${formatDuration(duration)}</div>`;
                }
                // value 展示
                let valueStr = '';
                if (item.value) {
                    let v = '';
                    try {
                        v = typeof item.value === 'object' ? JSON.stringify(item.value) : item.value;
                    } catch(e) { v = item.value; }
                    valueStr = `<div class='search-result-value'>${v}</div>`;
                }
                // 判断是否使用竖图展示
                const isVertical = ['MOVIE', 'SEASON', 'ACTOR'].includes(group.searchType);
                const cardClass = isVertical ? 'search-result-item search-result-item-vertical' : 'search-result-item';
                const placeholderImage = isVertical ? '' : '';
                // 构建deeplink HTML
                let deeplinkHtml = '';
                if (Array.isArray(sourceDeeplinks) && sourceDeeplinks.length > 0) {
                    deeplinkHtml = '<div class="search-result-deeplinks">';
                    sourceDeeplinks.forEach(link => {
                        const sourceId = link.sourceId || '';
                        const sourceName = link.sourceName || '';
                        const sourceIcon = link.sourceIcon ? `<img src="${link.sourceIcon}" alt="icon">` : '';
                        deeplinkHtml += `
                            <div class="search-result-deeplink">
                                ${sourceIcon}
                                <span class="source-name">${sourceName}</span>
                                <span class="source-id">#${sourceId}</span>
                            </div>
                        `;
                    });
                    deeplinkHtml += '</div>';
                }
                // 展示发布日期（releaseTime）
                let releaseTimeStr = '';
                if (item.releaseTime) {
                    const d = new Date(Number(item.releaseTime));
                    if (!isNaN(d.getTime())) {
                        const y = d.getFullYear();
                        const m = (d.getMonth()+1).toString().padStart(2,'0');
                        const day = d.getDate().toString().padStart(2,'0');
                        releaseTimeStr = `<div class='search-result-date'>${y}-${m}-${day}</div>`;
                    }
                }
                const $item = $(`
                    <div class="${cardClass}" tabindex="0">
                        <img src="${image}" alt="${name}" onerror="this.src='${placeholderImage}'">
                        <div class="search-result-content">
                            <div class="search-result-name">${name}</div>
                            ${categoriesStr}${videoScoresStr}${seasonInfoStr}${durationStr}
                            ${releaseTimeStr}
                            ${valueStr}
                            ${deeplinkHtml}
                        </div>
                    </div>
                `);
                // 新增：卡片点击跳转详情页
                $item.off('click').on('click', function() {
                    let v = item.value;
                    let objectType = '';
                    try {
                        if (typeof v === 'string') v = JSON.parse(v);
                    } catch(e) {}
                    if (v && typeof v === 'object' && v.objectType) objectType = v.objectType;
                    if (objectType === 'MOVIE') {
                        window.open(`movie-detail.html?token=${encodeURIComponent(globalToken)}&value=${encodeURIComponent(JSON.stringify(v))}`, '_blank');
                    } else if (objectType === 'SEASON') {
                        window.open(`season-detail.html?token=${encodeURIComponent(globalToken)}&value=${encodeURIComponent(JSON.stringify(v))}`, '_blank');
                    } else if (objectType === 'VIDEO') {
                        window.open(`video-detail.html?token=${encodeURIComponent(globalToken)}&value=${encodeURIComponent(JSON.stringify(v))}`, '_blank');
                    } else if (objectType === 'ACTOR') {
                        window.open(`people-detail.html?token=${encodeURIComponent(globalToken)}&value=${encodeURIComponent(JSON.stringify(v))}`, '_blank');
                    }
                });
                $list.append($item);
            });
            // 添加折叠功能
            let expanded = true;
            $title.click(function() {
                expanded = !expanded;
                if (expanded) {
                    $list.show();
                    $icon.text('▼');
                } else {
                    $list.hide();
                    $icon.text('▶');
                }
            });
            $group.append($title).append($list);
            $results.append($group);
        });
    }
    // 高亮当前菜单
    $(function() {
        const page = location.pathname.split('/').pop();
        $('.sidebar .nav-link').each(function() {
            const href = $(this).attr('href');
            if (href === page) {
                $(this).addClass('active');
            } else {
                $(this).removeClass('active');
            }
        });
    });
    $(function() {
        $('body').off('click', '#tokenDisplay').on('click', '#tokenDisplay', async function() {
            globalToken = $('#tokenText').text();
            if (!globalToken || globalToken === 'Failed to generate' || globalToken === 'Generating...') {
                alert('当前无可用token');
                return;
            }
            try {
                await navigator.clipboard.writeText(globalToken);
                const $btn = $(this);
                $btn.removeClass('btn-outline-success').addClass('btn-success');
                $btn.addClass('copied');
                setTimeout(() => {
                    $btn.removeClass('btn-success').addClass('btn-outline-success');
                    $btn.removeClass('copied');
                }, 1500);
            } catch (err) {
                alert('Copy failed, please select the token manually');
            }
        });
    });
    </script>
</body>
</html> 